// AbstractController.java
package org.zjx.core.controller;

import lombok.SneakyThrows;
import org.zjx.core.*;
import org.zjx.core.client.MemoryActionPuller;
import org.zjx.core.engine.DecisionEngine;
import org.zjx.core.engine.InterruptManager;
import org.zjx.core.model.InterruptEvent;
import org.zjx.core.monitor.DecisionMonitor;
import org.zjx.core.nodes.*;
import org.zjx.core.state.*;
import org.zjx.exception.*;

import java.time.Instant;
import java.util.*;
import java.util.function.Supplier;

/**
 * 控制器抽象基类 - 这是游戏或系统控制器的核心抽象类，提供了决策处理、状态管理和中断处理的基础功能。
 * 子类需要实现具体的决策树构建和中断注册逻辑。
 */
public abstract class AbstractController {
    // 决策引擎，负责根据当前状态和决策树做出决策
    protected final DecisionEngine decisionEngine;

    // 中断管理器，负责处理各种中断事件
    protected final InterruptManager interruptManager = new InterruptManager();

    // 决策树注册中心，用于管理和查找决策树
    protected final DecisionTreeRegistry treeRegistry = new DecisionTreeRegistry();

    protected final StateAccessor stateAccessor;

    /**
     * 构造函数
     * @param validator 状态验证器，用于验证状态的有效性
     */
    protected AbstractController(StateValidator validator,StateAccessor stateAccessor) {
        Objects.requireNonNull(validator, "StateValidator must not be null");
        Objects.requireNonNull(stateAccessor, "StateAccessor must not be null");

        this.stateAccessor = stateAccessor;

        // 初始化决策引擎，传入中断管理器、动作拉取器、决策树、验证器和监控器
        this.decisionEngine = new DecisionEngine(
                interruptManager,
                new MemoryActionPuller(),
                buildDomainDecisionTree(),
                validator,
                createDecisionMonitor()
        );

        // 注册核心中断（如超时中断）
        registerCoreInterrupts();

        // 注册领域特定的中断
        registerDomainInterrupts();
    }

    /**
     * 抽象方法 - 子类必须实现：构建领域特定的决策树
     */
    protected abstract DecisionTree buildDomainDecisionTree();

    /**
     * 抽象方法 - 子类必须实现：注册领域特定的中断
     */
    protected abstract void registerDomainInterrupts();

    /**
     * 注册子决策树
     * @param treeId 决策树ID
     * @param tree 决策树实例
     * @return 注册的决策树
     */
    protected DecisionTree registerSubTree(String treeId, DecisionTree tree) {
        treeRegistry.register(treeId, tree);
        return tree;
    }

    /**
     * 获取子决策树
     * @param treeId 决策树ID
     * @return 决策树实例
     * @throws DecisionConfigurationException 如果决策树不存在
     */
    protected DecisionTree getSubTree(String treeId) {
        return treeRegistry.get(treeId)
                .orElseThrow(() -> new DecisionConfigurationException(
                        "SubTree not found: " + treeId));
    }

    /**
     * 公共API - 处理动作
     * @param clientId 客户端ID
     */
    public void processAction(String clientId) {
        Objects.requireNonNull(clientId, "Client ID must not be null");
        // 将主任务推送到决策引擎
        decisionEngine.pushMainTask(new ClientTaskNode(clientId), stateAccessor);
    }

    /**
     * 公共API - 轮询动作
     * @param clientId 客户端ID
     * @param accessor 状态访问器
     * @return 可选的游戏动作
     */
    @SneakyThrows
    public Optional<GameAction> pollAction(String clientId, StateAccessor accessor) {
        Objects.requireNonNull(clientId, "Client ID must not be null");
        Objects.requireNonNull(accessor, "State accessor must not be null");
        return decisionEngine.nextAction(clientId, accessor);
    }

    /**
     * 中断系统 - 注册核心中断
     */
    protected void registerCoreInterrupts() {
        registerTimeoutInterrupt();
    }

    /**
     * 中断系统 - 注册超时中断
     */
    protected void registerTimeoutInterrupt() {
        final TimeoutConfig config = provideTimeoutConfig();
        if (config != null && config.isValid()) {
            interruptManager.register(InterruptEvent.createWithAccessorCondition(
                    config.priority(),
                    config.eventType(),
                    () -> config.actionNodeSupplier().get(),
                    (accessor, params) -> accessor.getComponent(config.stateType())
                            .filter(TimeoutCapable.class::isInstance)
                            .map(TimeoutCapable.class::cast)
                            .map(TimeoutCapable::isTimeout)
                            .orElse(false),1000
            ));
        }
    }

    /**
     * 中断系统 - 提供超时配置（默认不启用）
     */
    protected TimeoutConfig provideTimeoutConfig() {
        return null;
    }

    /**
     * 内部类 - 客户端任务节点，表示一个客户端任务
     */
    private static class ClientTaskNode implements DecisionNode {
        private final String clientId;

        ClientTaskNode(String clientId) {
            this.clientId = clientId;
        }

        @Override
        public GameAction decide(DecisionContext context) {
            context.getLocalParams().put("clientId", clientId);
            return null; // 由后续节点处理
        }
    }

    /**
     * 配置类 - 超时配置
     */
    public record TimeoutConfig(
            Class<? extends StateComponent> stateType,  // 状态类型
            String eventType,                         // 事件类型
            InterruptEvent.Priority priority,         // 中断优先级
            Supplier<ActionNode> actionNodeSupplier   // 动作节点供应商
    ) {
        public static final TimeoutConfig EMPTY = new TimeoutConfig(null, null, null, null);

        /**
         * 检查配置是否有效
         */
        public boolean isValid() {
            return stateType != null && eventType != null &&
                    priority != null && actionNodeSupplier != null &&
                    TimeoutCapable.class.isAssignableFrom(stateType);
        }
    }

    /**
     * 监控创建 - 创建决策监控器
     */
    private DecisionMonitor createDecisionMonitor() {
        Set<String> monitoredNodes = new HashSet<>();
        monitoredNodes.add("ActionNode");
        monitoredNodes.add("ConditionNode");
        monitoredNodes.add("ParallelNode");
        return new DecisionMonitor(0.5, monitoredNodes, 100);
    }
}